package com.hq.ims.data.alisms;

import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import com.hq.ims.data.utils.LocalConstant;
import com.hq.utils.exception.CommonException;
import com.hq.utils.util.JsonUtils;
import com.hq.utils.util.StringUtils;
import com.hq.web.utils.RedisUtils;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class AliSmsConfig {

    /**
     * 阿里sms accessKeyId
     */
    @Value("${userAttribute.aliSms.accessKeyId}")
    private String accessKeyId;

    /**
     * 阿里sms accessKeySecret
     */
    @Value("${userAttribute.aliSms.accessKeySecret}")
    private String accessKeySecret;

    /**
     * 短信签名
     */
    @Value("${userAttribute.aliSms.smsSignName}")
    private String smsSignName;

    /**
     * 短信域名
     */
    @Value("${userAttribute.aliSms.domain}")
    private String domain;

    /**
     * 短信code
     */
    @Value("${userAttribute.aliSms.smsCode}")
    private String smsCode;

    @Resource
    private RedisTemplate<String, String> redisTemplate;


    /**
     * 使用AK&SK初始化账号Client
     *
     * @return Client
     * @throws Exception
     */
    private com.aliyun.dysmsapi20170525.Client createClient(String ak, String aks) throws Exception {
        Config config = new Config()
                .setAccessKeyId(ak)
                .setAccessKeySecret(aks);
        config.endpoint = domain;
        return new com.aliyun.dysmsapi20170525.Client(config);
    }

    public void sendVerifyMobileSms(@NonNull String mobile) {
        Map<String, String> param = new HashMap<>(1);
        String randomCode = getRandomNumber(6);
        param.put("verifyCode", randomCode);
        String paramStr = JsonUtils.objectToString(param);
        this.sendSms(smsCode, mobile, paramStr);

        //记录到redis中 短信有效期十分钟
        redisTemplate.opsForValue().set(LocalConstant.REDIS_KEY_SMS + mobile, randomCode, 10, TimeUnit.MINUTES);
    }

    /**
     * 校验code是否正确
     */
    public Boolean checkVerifyMobileSms(
            @NonNull String mobile,
            @NonNull String paramCode
    ) {
//        String code = redisTemplate.opsForValue().get(LocalConstant.REDIS_KEY_SMS + mobile);
        String code = (String) RedisUtils.getRedisTemplate().opsForValue().get(LocalConstant.REDIS_KEY_SMS + mobile);
        if (StringUtils.isEmpty(code)) {
            throw CommonException.build("验证码已过期");
        }
        if (paramCode.equals(code)) {
            return true;
        }
        return false;
    }

    /**
     * 删除code
     */
    public Boolean deleteVerifyMobileSms(@NonNull String mobile) {
        String code = redisTemplate.opsForValue().get(LocalConstant.REDIS_KEY_SMS + mobile);
        if (StringUtils.isNotEmpty(code)) {
            redisTemplate.delete(LocalConstant.REDIS_KEY_SMS + mobile);
        }
        return true;
    }

    private String getRandomNumber(int len) {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < len; i++) {
            sb.append(random.nextInt(10));
        }
        return sb.toString();
    }


    /**
     * 发送短信
     *
     * @param smsCode 验证码
     * @param phone   手机号 可为多个以 , 分隔
     * @param param   参数 {}
     */
    public boolean sendSms(
            @NonNull String smsCode,
            @NonNull String phone,
            String param
    ) {

        try {
            //创建sms对象
            com.aliyun.dysmsapi20170525.Client client = createClient(accessKeyId, accessKeySecret);

            //组合参数
            SendSmsRequest sendSmsRequest = new SendSmsRequest()
                    .setPhoneNumbers(phone)
                    .setSignName(smsSignName)
                    .setTemplateCode(smsCode);

            if (StringUtils.isNotEmpty(param)) {
                sendSmsRequest.setTemplateParam(param);
            }

            // 发送并获取结果
            SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);

            if (sendSmsResponse != null && "OK".equals(sendSmsResponse.getBody().getCode())) {
                //todo 可存储返回结果做短信发送记录
                log.info("阿里云SMS调用正确，结果：" + sendSmsResponse.getBody().toString());
                return true;
            } else {
                log.info("阿里云SMS调用错误，结果：" + sendSmsResponse.getBody().getMessage());
                return false;
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("短信发送失败！ 号码为" + phone);
            return false;
        }

    }


}
